package com.bestcem.xm.script.controller;

import cn.hutool.core.lang.ObjectId;
import com.bestcem.xm.common.core.domain.web.ServiceResult;
import com.bestcem.xm.common.core.domain.web.XmResultJson;
import com.bestcem.xm.component.security.annotation.AuthIgnore;
import com.bestcem.xm.componet.redis.service.RedisService;
import com.bestcem.xm.om.enums.OpenPlantFormBookingIndustryEnum;
import com.bestcem.xm.user.config.properties.SingleOrgProperties;
import com.bestcem.xm.user.constant.RedisKeyConstant;
import com.bestcem.xm.user.constant.UserCacheKeyConstant;
import com.bestcem.xm.user.dao.OrganizationDao;
import com.bestcem.xm.user.dao.OrganizationQuotainfoDao;
import com.bestcem.xm.user.entity.pojo.OrganizationQuotainfoDO;
import com.bestcem.xm.user.enums.QuotaConsumptionEnum;
import com.bestcem.xm.user.service.dto.init.InitOrgRequestDTO;
import com.bestcem.xm.user.service.dto.role.UserRoleDTO;
import com.bestcem.xm.user.service.dto.user.OrganizationDTO;
import com.bestcem.xm.user.service.init.UserDataInitService;
import com.bestcem.xm.user.service.init.UserInitService;
import com.bestcem.xm.user.util.business.UserCacheUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 初始化数据controller
 *
 * @author wangyunyun <yunyun.wang@idiaoyan.com>
 * @version v1.0
 * @date 2022/7/13 10:26
 */
@Slf4j
@AuthIgnore
@RestController
@RequestMapping(value = "/user/init")
public class UserDataInitController {
    @Resource
    private UserInitService userInitService;
    @Resource
    private UserDataInitService userDataInitService;
    @Resource
    private com.bestcem.xm.om.service.InitDataService initDataService;
    //@Resource
    //private HttpServletRequest request;
    @Resource
    private SingleOrgProperties singleOrgProperties;
    @Value("${app.xm.is-baseline:true}")
    private boolean isBaseline;
    @Resource
    private UserCacheUtil userCacheUtil;
    @Resource
    private RedisService redisService;

    private static final String LOCAL_HOST_IPV6 = "0:0:0:0:0:0:0:1";
    private static final String LOCAL_HOST_IPV4 = "127.0.0.1";

    @AuthIgnore
    @GetMapping("/main")
    public void main() throws ParseException {
        //String ip = IpAddressUtil.getIpAddress(request);
        //if (!LOCAL_HOST_IPV6.equals(ip) && !LOCAL_HOST_IPV4.equals(ip)) {
        //    log.error("[user init data]只允许本机执行,ip={}", ip);
        //    return;
        //}

        // systems = init_subsystem()
        // @以诺（昌鹏涛）: 不需要了
        // mod_ids = init_module(None, systems)
        initDataService.initModule();
        log.info("初始化脚本, initModule执行完成....");
        // init_submodule()
        initDataService.initSubmodule();
        log.info("初始化脚本, initSubmodule执行完成....");
        // init_domain()
        initDataService.initDomain();
        log.info("初始化脚本, initDomain执行完成....");
        // init_industry()
        initDataService.initIndustry();
        log.info("初始化脚本, initIndustry执行完成....");
        // init_free_organization(None)
        userInitService.initFreeOrganization();
        log.info("初始化脚本, initFreeOrganization执行完成....");
        // role = init_super_role()
        // @张依方: 表不用了, 方法不需要了

        // reset_rolepermission('投放审核（系统）')
        userInitService.resetRolePerms("投放审核（系统）");
        log.info("初始化脚本, resetRolePerms执行完成....");
        // del_validate_fail_smtp()
        userInitService.delValidateFailSmtp();
        log.info("初始化脚本, delValidateFailSmtp执行完成....");
        // add_system_smtp(None)
        userInitService.addSystemSmtp();
        log.info("初始化脚本, addSystemSmtp执行完成....");
        // set_org_inner(None)
        userInitService.setOrgInner();
        log.info("初始化脚本, setOrgInner执行完成....");
        // set_user_is_accept_is_true_and_is_inner_user(None)
        userInitService.updateAcceptAndInnerUser();
        log.info("初始化脚本, updateAcceptAndInnerUser执行完成....");
        // set_brand(None)
        userInitService.setBrand();
        log.info("初始化脚本, setBrand执行完成....");

        // 私有部署逻辑
        if (isBaseline) {
            // 初始化一个旗舰版套餐 init_flagship_pack()
            String packId = initDataService.initFlagShipPack("旗舰版");

            InitOrgRequestDTO initOrgRequestDTO = new InitOrgRequestDTO();
            initOrgRequestDTO.setCode(singleOrgProperties.getCode());
            initOrgRequestDTO.setName(singleOrgProperties.getName());
            initOrgRequestDTO.setContent(singleOrgProperties.getContent());
            initOrgRequestDTO.setEmail(singleOrgProperties.getEmail());
            // initOrgRequestDTO.setMobile(singleOrgProperties.getMobile());
            if (Objects.nonNull(singleOrgProperties.getExpireDt())) {
                Date date = new SimpleDateFormat("yyyy-MM-dd").parse(singleOrgProperties.getExpireDt());
                initOrgRequestDTO.setExpireDt(date);
                initOrgRequestDTO.setFormalExpireTime(date);
            }

            if (StringUtils.isEmpty(singleOrgProperties.getIndustryCode())) {
                initOrgRequestDTO.setIndustryCode(OpenPlantFormBookingIndustryEnum.APPLICANT_TRADE_OTHER.getIndex() + "");
            } else {
                initOrgRequestDTO.setIndustryCode(singleOrgProperties.getIndustryCode());
            }
            initOrgRequestDTO.setPackageId(packId);
            initOrgRequestDTO.setFormalPackageId(packId);
            // org = init_organization(**settings.SINGLE_ORG)
            ServiceResult<OrganizationDTO> organizationDTOServiceResult = userInitService.initOrganization(initOrgRequestDTO);
            OrganizationDTO org = organizationDTOServiceResult.getData();
            if (Objects.isNull(org) || ObjectUtils.isEmpty(org.getOrgId())) {
                log.error("[User] 初始化脚本, 私有部署 租户 创建错误");
                return;
            }
            // 初始化钱包 create_corporate_wallet()
//            userInitService.createCorporateWallet(singleOrgProperties.getCode());
//            log.info("初始化脚本, createCorporateWallet执行完成....");
            // 初始化默认邮箱 add_system_smtp(None)
            userInitService.addSystemSmtp();
            log.info("初始化脚本, addSystemSmtp执行完成....");
            // admin_role = init_admin_role(org.oid)
            ServiceResult<UserRoleDTO> userRoleDTOServiceResult = userInitService.initAdminRoleAndPerms(org.getOrgId());
            UserRoleDTO adminRole = userRoleDTOServiceResult.getData();
            if (Objects.isNull(adminRole)) {
                log.error("[User] 初始化脚本, 私有部署 系统管理员角色 创建错误 orgId:{}", org.getOrgId());
                return;
            }
            log.info("初始化脚本, initAdminRoleAndPerms执行完成....");
            // init_super_admin(admin_role, org.oid)
            userInitService.initAdminUser(adminRole, org.getOrgId());
            log.info("初始化脚本, initAdminUser执行完成....");
            // init_senior_admin(org.oid)
            userInitService.initSeniorAdminRoleAndPerms(org.getOrgId());
            log.info("初始化脚本, initSeniorAdminRoleAndPerms执行完成....");
            // delete_package_cache()
            initDataService.deletePackageCache();
            log.info("初始化脚本, deletePackageCache执行完成....");
            // init_org_mfasetting()
            userInitService.initOrgMfaSetting();
            log.info("初始化脚本, initOrgMfaSetting执行完成....");
            //初始化消息模板
            userInitService.initDefaultTemplate(org.getOrgId());
            log.info("初始化脚本, initDefaultTemplate执行完成....");
            // 这里用error日志是为了防止生产环境执行脚本看不到info日志 print(f"Initial organization{settings.SINGLE_ORG}.")
            log.error("[User] 初始化脚本, 私有部署 {}", singleOrgProperties);
        }

        // convert_rolepermission()
    }


    /**
     * 初始化公司企业企业钱包配置
     *
     * @return String
     * @author wangyunyun <yunyun.wang@idiaoyan.com>
     * @date 2022/7/13 10:39
     */
    @GetMapping("/org_wallet_config")
    public XmResultJson<String> orgWalletConfig(HttpServletRequest request) {
        // 校验
        //String ip = IpAddressUtil.getIpAddress(request);
        //if (!LOCAL_HOST_IPV6.equals(ip)) {
        //    return XmResultJson.fail(ReqErrorCodeEnum.SERVER_ERROR.getCode(), "只允许本机执行");
        //}

        // 初始化公司企业企业钱包配置
        ServiceResult<String> result = userDataInitService.orgWalletConfigInit();

        // 处理失败
        if (!result.isSuccess()) {
            return XmResultJson.fail(Integer.valueOf(result.getErrorCode()), result.getMsg());
        }
        // 处理成功
        return XmResultJson.success(result.getData());
    }

    @GetMapping("/quota")
    public String initQuota(String id, HttpServletRequest request) {
        //String ip = IpAddressUtil.getIpAddress(request);
        //if (!LOCAL_HOST_IPV6.equals(ip)) {
        //    return "只允许本机执行";
        //}
        // 临时刷新限额方法
        this.init(id);
        // 处理成功
        return "success";
    }

    @Resource
    private OrganizationDao userOrganizationDao;
    @Resource
    private OrganizationQuotainfoDao organizationQuotainfoDao;

    private void init(String id) {
        List<String> orgIdsList = Collections.singletonList(id);
        if (StringUtils.isEmpty(id)) {
            orgIdsList = userOrganizationDao.listAllIds();
        }
        for (String orgId : orgIdsList) {
            if (ObjectId.isValid(orgId)) {
                String accountCountKey = RedisKeyConstant.getOrgAccountCountKey(orgId);
                Integer accountCount = Integer.valueOf(userCacheUtil.get(accountCountKey));
                String qdesCountKey = RedisKeyConstant.getOrgProjectCountKey(orgId);
                Integer qdesCount = Integer.valueOf(userCacheUtil.get(qdesCountKey));
                String respondentCountKey = RedisKeyConstant.getOrgRespondentCountKey(orgId);
                Long respondentCount = userCacheUtil.incrBy(respondentCountKey);

                OrganizationQuotainfoDO quotaInfo = organizationQuotainfoDao.getByOrgId(orgId);
                if (Objects.isNull(quotaInfo)) {
                    // 新增一条数据
                    quotaInfo = new OrganizationQuotainfoDO();
                    quotaInfo.setOrgId(orgId);
                    organizationQuotainfoDao.insertSelective(quotaInfo);
                }
                quotaInfo.setOrgId(orgId);
                quotaInfo.setUserTotal(Objects.isNull(accountCount) ? 0 : accountCount);
                quotaInfo.setRespondentTotal(Objects.isNull(respondentCount) ? 0 : respondentCount.intValue());
                quotaInfo.setProjectTotal(Objects.isNull(qdesCount) ? 0 : qdesCount);
                quotaInfo.setMemberIndTotal(0);
                quotaInfo.setDatasourceTotal(0);
                String consumption = UserCacheKeyConstant.USER_PACK_CONSUMPTION + orgId;
                redisService.del(consumption);
                redisService.hashIncr(consumption, QuotaConsumptionEnum.USER.getKey(), Long.valueOf(Optional.ofNullable(quotaInfo.getUserTotal()).orElse(0)));
                redisService.hashIncr(consumption, QuotaConsumptionEnum.RESPONDENT.getKey(), Long.valueOf(Optional.ofNullable(quotaInfo.getRespondentTotal()).orElse(0)));
                redisService.hashIncr(consumption, QuotaConsumptionEnum.PROJECT.getKey(), Long.valueOf(Optional.ofNullable(quotaInfo.getProjectTotal()).orElse(0)));
                redisService.hashIncr(consumption, QuotaConsumptionEnum.MEMBER_IND.getKey(), Long.valueOf(Optional.ofNullable(quotaInfo.getMemberIndTotal()).orElse(0)));
                redisService.hashIncr(consumption, QuotaConsumptionEnum.DATASOURCE.getKey(), Long.valueOf(Optional.ofNullable(quotaInfo.getDatasourceTotal()).orElse(0)));
                organizationQuotainfoDao.updateQuotaConsumption(quotaInfo);
            }
        }
    }
}
